/* global $, visoConfig, Mustache, uuid, jsPlumb, graphlib */
jQuery(document).ready(function () {
  //页面初始化
  WebEpdFileJsPlumb.init();
});
var WebEpdFileJsPlumb = function () {
  var instJsPlumb=null;
  var configOpt={
      //主区域
      mainAreaId:'mainAreaJsPlumb',
      mainArea:'#mainAreaJsPlumb',
      //流程图区域
      workflowAreaId:'workflowAreaJsPlumb',
      workflowArea:'#workflowAreaJsPlumb',
      //工具栏区域
      toolsArea:'#toolsAreaJsPlumb',
      //是否显示参数关系
      isShowVarRefLine:true,
      //数据
      dataWorkflow:null,
  };

  function uuidG() {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";
  
    var uuid = s.join("");
    return uuid;
  }

  // 放入拖动节点
  function dropNode (template, position) {
    position.left -= $(configOpt.toolsArea).outerWidth()
    position.id = uuidG()
    position.generateId = uuidG()
    var html = renderHtml(template, position)

    $(configOpt.workflowArea).append(html)

    initSetNode(template, position.id)
  }

  // 初始化节点设置
  function initSetNode (template, id) {
    addDraggable(id)

  }

  // 设置入口点
  function setEnterPoint(id, position,type) {
    type = type?type:connectorType.varRefLine;
    if (!configOpt.isShowVarRefLine&&type===connectorType.varRefLine) {return;}
    var config = getBaseNodeConfig(type)

    config.isSource = false
    config.maxConnections = -1

    return instJsPlumb.addEndpoint(id, {
      anchors: position || 'Top',
      uuid: id + '-in'
    }, config)
  }

  // 设置出口点
  function setExitPoint(id, position, type) {
    type = type?type:connectorType.varRefLine;
    if (!configOpt.isShowVarRefLine&&type===connectorType.varRefLine) {return;}
    var config = getBaseNodeConfig(type)

    config.isTarget = false
    config.maxConnections = -1

    return instJsPlumb.addEndpoint(id, {
      anchors: position || 'Bottom',
      uuid: id + '-out'
    }, config)
  }


  // 删除一个节点以及
  function emptyNode (id) {
    if (confirm('确定删除吗？')) {
      instJsPlumb.remove(id)
    }
  }

  // 让元素可拖动
  function addDraggable(id, toggle) {
    instJsPlumb.draggable(id, {
      containment: 'parent'
    })

    if (!toggle) {
      instJsPlumb.toggleDraggable(id);
    }
  }

  // 渲染html
  function renderHtml (type, position) {
    return Mustache.render($('#' + type).html(), position)
  }

  function eventHandler(target) {
    var data = target.dataset;
    if (data.type === 'deleteNode') {
      emptyNode(data.id)
    } else if (data.type === 'toggleDraggable') {
      // console.log(target)
      if ($(target).hasClass(data.lock)) {
        //icon
        $(target).removeClass(data.lock).addClass(data.unlock)
        //cursor 
        $('#' + data.id).removeClass('pa-move').addClass('pa-move')

      } else {
        $(target).removeClass(data.unlock).addClass(data.lock)
        //cursor 
        $('#' + data.id).removeClass('pa-move')
      }
      instJsPlumb.toggleDraggable(data.id);
    }
  }

  // 链接建立后的检查
  // 当出现自连接的情况后，要将链接断开
  function connectionBeforeDropCheck (info) {
    if (!info.connection.source.dataset.pid) {
      return true
    }
    return info.connection.source.dataset.pid !== info.connection.target.dataset.id
  }

  var connectorType = {flowchart:"flowchart",varRefLine:"varRefLine",refLine:"refLine"}

  // 获取基本配置
  function getBaseNodeConfig (type) {
    if (type===connectorType.flowchart) {
      return Object.assign({connType:type}, visoConfig.baseStyleFlowchart)
    } else if (type===connectorType.varRefLine){     
      return Object.assign({connType:type}, visoConfig.baseStyleBezier)
    } else if (type===connectorType.refLine){     
      return Object.assign({connType:type}, visoConfig.baseStyleRefLine)
    }
  }

  // 初始化开始节点属性
  function initBeginNode (id) {
    var config = getBaseNodeConfig(connectorType.flowchart)

    config.isTarget = false
    config.maxConnections = 1

    instJsPlumb.addEndpoint(id, {
      anchors: 'Right',
      uuid: id + '-out'
    }, config)
  }

  // 初始化结束节点属性
  function initEndNode (id) {
    var config = getBaseNodeConfig(connectorType.flowchart)

    config.isSource = false

    instJsPlumb.addEndpoint(id, {
      anchors: 'Top',
      uuid: id + '-in'
    }, config)
  }

  var DataProcess = {
    inputData: function (nodes) {
      var ids = this.getNodeIds(nodes)
      var g = new graphlib.Graph()

      ids.forEach(function (id) {
        g.setNode(id)
      })

      var me = this

      nodes.forEach(function (item) {
        if (me['dealNode' + item.type]) {
          me['dealNode' + item.type](g, item)
        } else {
          console.error('have no deal node of ' + item.type)
        }
      })

      var distance = graphlib.alg.dijkstra(g, 'Start')

      return this.generateDepth(distance)
    },
    setNodesPosition: function (nodes) {
      var me = this
      nodes.forEach(function (item) {
        me.getNodePosition(item)
      })
    },
    getNodePosition: function (node) {
      var $node = document.getElementById(node.id)
      node.top = parseInt($node.style.top)
      node.left = parseInt($node.style.left)
    },
    generateDepth: function (deep) {
      var depth = []

      Object.keys(deep).forEach(function (key) {
        var distance = deep[key].distance

        if (!depth[distance]) {
          depth[distance] = []
        }

        depth[distance].push(key)
      })

      return depth
    },
    getNodeIds: function (nodes) {
      return nodes.map(function (item) {
        return item.id
      })
    },
    dealNodeRoot: function (g, node) {
      this.setEdge(g, node.id, node.data.nextNode)
    },

    dealNodeExit: function (g, node) {

    },
    //LogicalBlockIntputPara
    dealNodeLogicalBlockIntputPara: function (g, node) {
      this.setEdge(g, node.id, node.data.nextNode)
    },

    //LogicalBlock
    dealNodeLogicalBlock: function (g, node) {
    },
    //LogicalBlockGcs
    dealNodeLogicalBlockGcs: function (g, node) {
    },
    //LogicalBlockVar
    dealNodeLogicalBlockVar: function (g, node) {
      this.setEdge(g, node.id, node.data.nextNode)
    },
    //LogicalBlockApvp
    dealNodeLogicalBlockApvp: function (g, node) {
      this.setEdge(g, node.id, node.data.nextNode)
    },
    //LogicalBlockDesignDrwNo
    dealNodeLogicalBlockDesignDrwNo: function (g, node) {
      this.setEdge(g, node.id, node.data.nextNode)
    },
    //LogicalBlockCurPartProp
    dealNodeLogicalBlockCurPartProp: function (g, node) {
      // this.setEdge(g, node.id, node.data.nextNode)
    },
    //LogicalBlockDowhile
    dealNodeLogicalBlockDowhile: function (g, node) {
      this.setEdge(g, node.id, node.data.nextNode)
      this.setEdge(g, node.id, node.data.nextNodeDowhile)
    },
    //LogicalBlockSelectPartTable
    dealNodeLogicalBlockSelectPartTable: function (g, node) {
      this.setEdge(g, node.id, node.data.nextNode)
    },

    setEdge: function name (g, from, to) {
      g.setEdge(from, to)
    }
  };

 
  function getCondiTableXY(dataCondiTable) {
    if (dataCondiTable) {
      tempstr = '';
      dataCondiTable.forEach(function (pItem) {
        tempstr = tempstr + '<tr>';
        var crcTag = '';
        if (pItem.changerc) {
          crcTag = '<a  class="hoverPopoverKeep" \
            data-container="body" data-placement="left"  \
            data-content="' + pItem.changerc + '"  \
            data-original-title="变更记录"> \
            <i class="fa fa-play fa-rotate-90 font-red"></i> </a>';
        }
        if (pItem.remark!==undefined) {
          tempstr = tempstr + '<td> ' + crcTag + pItem.remark + ' </td>';
        }
        for (let index = 0; index < 10; index++) {
          condiClass = '';
          if (pItem['condi'+(index+1).toString()]) {
            var condi = pItem['condi'+(index+1).toString()];
            if (condi.type === 'para') {
              condiClass = 'success';
            }else if (condi.type === 'ret') {
              condiClass = 'info';
            }else if (condi.type === 'value') {
              condiClass = 'danger';
            }else if (condi.type === 'PNQT') {
              condiClass = 'active';
            }
            tempstr = tempstr + '<td class="' + condiClass + '"> ' + condi.value + ' </td>';
          }
        }
        tempstr = tempstr + '</tr>';
      });
      var condiTable = ' \
      <div class="table-scrollable" style="max-height:200px;overflow:scroll;"> \
        <table class="table table-bordered table-hover"> \
            <tbody>'
        + tempstr +
        '</tbody> \
          </table> \
      </div>';
      return condiTable;
    }
    return '';
  }


  function getNodeData(item, vardefineInfos,props) {
    var data = {
      id: item.id,
      name: item.name,
      comment: item.comment,
      no: item.no,
      desc: item.desc,
      condition: item.condition,
      width: item.width,
      top: item.top,
      left: item.left,
      choices: item.choices || [],
      showData: {},
    };
    if (item.type === 'LogicalBlockVar') {
      //title
      data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockVar" \
      data-original-title="变量赋值块" data-content="块序号:'+item.orderId+'<br>块备注:'+item.name +'" \
      data-container="body" data-placement="left" ><i class="fa fa-server fa-rotate-180 font-red"></i></a> '
      +item.orderId+','+item.name;

      //varlist
      data.choices.forEach(function (chItem) {
        var defVar = vardefineInfos.find(function (x) {
          if (x.no === chItem.no) {
            return x;
          };
        });
        if (defVar) {
          chItem.area = defVar.area;
          chItem.flag = defVar.flag;
          chItem.desc = defVar.desc;
          chItem.unit = defVar.unit;
          chItem.values = defVar.values;
          chItem.defaultValue = defVar.defaultValue;
          chItem.dataType = defVar.dataType;
          chItem.level = defVar.level;
        }
        //leftIcon
        var leftIconTitle = '变量信息';
        var leftIcon = 'fa fa-vimeo font-blue-sharp';
        var leftIconTip = '名称: ' + chItem.no
          + '<br>描述: ' + chItem.desc + '<br>单位: ' + chItem.unit
          + '<br>取值: ' + chItem.values + '<br>默认值: ' + chItem.defaultValue + '<br>标识: ' + chItem.flag;

        //link
        var linkIcon='';
        if (chItem.link) {
          if (chItem.link===chItem.no) {
            linkIcon = '<i class="fa fa-link font-blue"></i>';
          } else {
            linkIcon = '<i class="fa fa-link font-dark"></i>';
          }
        }

        //rightIcon
        var rightIconTitle,rightIconTip,rightIcon
        if (chItem.getGcs) { //使用全局逻辑赋值
          rightIconTitle = chItem.no+' = 全局逻辑赋值';
          rightIconTip ='<a class="pull-right" data-toggle="modal" href="#modalGetGcsEditor"><i class="fa fa-pencil-square font-blue"></i></a>文件编号:' + chItem.getGcs.no
          + '<br>文件描述:' + chItem.getGcs.desc+ '<br>返回变量:' + chItem.getGcs.retVars + '<br>传入变量:' + chItem.getGcs.invars+ '<br>函数名称:'+ chItem.getGcs.funcName;
            rightIcon = 'fa fa-file-code-o font-blue-sharp';
        }else if (chItem.getSdt) { //使用SD表格赋值
          rightIconTitle = chItem.no+' = SD表赋值';
          rightIconTip ='<a class="pull-right" data-toggle="modal" href="#modalGetGcsEditor"><i class="fa fa-pencil-square font-blue"></i></a>SD表编号:' + chItem.getSdt.no
          + '<br>SD表描述:' + chItem.getSdt.desc+ '<br>返回列:' + chItem.getSdt.retVars + '<br>传入变量:' + chItem.getSdt.invars + '<br>函数名称:'+ chItem.getSdt.funcName;
            rightIcon = 'fa fa-calculator fa-rotate-180 font-blue-sharp';
        }else if (chItem.condition) { //condition table
          rightIconTitle = chItem.no+' = 条件表格赋值';
          rightIconTip = '条件表格<a class="pull-right" data-toggle="modal" href="#modalEditFormula"><i class="fa fa-pencil-square font-blue"></i></a>' +
          getCondiTableXY(chItem.condiTable);//'条件变量:' + chItem.condition + '<br>结果变量:' + chItem.conditionRet;
          rightIcon = 'fa fa-table font-blue-sharp';
        }else if (chItem.formulaType) { //condition table
          rightIconTitle = chItem.no+' = 数学公式赋值';
          rightIcon = 'fa fa-won fa-rotate-180 font-red';
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalRichEditor"><i class="fa fa-pencil-square font-blue"></i></a> = ' + chItem.formula;
          if (chItem.formula) {
            rightIcon = 'fa fa-won fa-rotate-180 font-blue-sharp';
          }
        }else {
          rightIconTitle = chItem.no+' = 表达式赋值';
          rightIcon = 'fa fa-magic font-red';
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalRichEditor"><i class="fa fa-pencil-square font-blue"></i></a> = ' + chItem.formula;
          if (chItem.formula) {
            rightIcon = 'fa fa-magic font-blue-sharp';
          }
        }
        var rightIconText=' \
                <a class="hoverPopoverKeep pull-right panel-node-LogicalBlockVar-rightIcon" \
                data-original-title="'+rightIconTitle+'" data-content=\''+rightIconTip+'\' \
                data-container="body" data-placement="left">'+linkIcon+'<i class="'+rightIcon+'"></i></a>';
        var leftIconText=' \
                <a class="hoverPopoverKeep panel-node-LogicalBlockVar-leftIcon" \
                data-original-title="'+leftIconTitle+'" data-content=\''+leftIconTip+'\'  \
                data-container="body" data-placement="left"><i class="'+leftIcon+'"></i></a>';
        //listItemText
        chItem.listItemText = rightIconText+leftIconText+chItem.no + ', ' + chItem.desc;
      });
    }else if (item.type === 'LogicalBlockIntputPara') {
      data.choices.forEach(function (chItem) {
        //leftIcon
        leftIcon = 'fa fa-vimeo-square font-blue-sharp';
        leftIconTitle = '变量信息:';
        leftIconTip = '名称: ' + chItem.no
          + '<br>描述: ' + chItem.desc + '<br>单位: ' + chItem.unit
          + '<br>取值: ' + chItem.values + '<br>默认值: ' + chItem.defaultValue + '<br>标识: ' + chItem.flag;
        //rightIcon
        chItem.listItemText =' <a href="#modalValGet" role="button" data-toggle="modal" class="hoverPopoverKeep" \
                data-original-title="'+leftIconTitle+'" data-content="'+leftIconTip+'" \
                data-container="body" data-placement="right"><i class="'+leftIcon+'"></i></a> '+chItem.no+','+chItem.desc;
      });
    }else if (item.type === 'LogicalBlockDowhile') {
      //title
      data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockDowhile" \
      data-original-title="DoWhile" data-content=\' \
      块序号:'+item.orderId+'<br>块备注:'+item.name+'\' \
      data-container="body"  data-placement="left" ><i class="fa fa-rotate-right font-blue-sharp"></i></a> '
      +item.orderId+','+item.name;
      //remark
      //data.showData.remark = item.comment;
      //条件表格信息
      // data.showData.conditionLeftIconTitle = '条件表格';
      var tempstr='';
      item.data.conditionVars.forEach(function (pItem) {
        var defVar = vardefineInfos.find(function (x) {
          if (x.no === pItem.no) {
            return x;
          };
        });
        var conditionVarTip='';
        if (defVar) {
          conditionVarTip='名称: ' + defVar.no + '<br>描述: ' + defVar.desc + '<br>单位: ' + defVar.unit
          + '<br>取值: ' + defVar.values + '<br>默认值: ' + defVar.defaultValue + '<br>标识: ' + defVar.flag;
        }
        var varText = pItem.no;
        if (pItem.formula&&pItem.formula!=="") {
          varText = pItem.no+"="+pItem.formula;
        }

        tempstr=tempstr+'<a href="#modalEditFormula" role="button" data-toggle="modal" class="hoverPopoverKeep" \
        data-original-title="变量信息" \
        data-content="'+conditionVarTip+'" \
        data-container="body"  data-placement="left" >'+varText+'</a>, ';
      });
      //条件表格
      var conditionRightIconTip='条件表格';//<a class="pull-right" data-toggle="modal" href="#modalSelectTable"><i class="fa fa-pencil-square font-blue"></i></a>
      var conditionRightIcon='<a href="#modalEditDowhile" role="button" data-toggle="modal" class="pull-right hoverPopoverKeep" \
      data-original-title="条件表格" data-content=\''+conditionRightIconTip+'\' \
      data-container="body"  data-placement="left" ><i class="fa fa-table font-green"></i></a>';
      data.showData.condition = conditionRightIcon+tempstr;
      data.showData.condiTable = getCondiTableXY(item.data.condiTable);

      //ListGetAtCol
      if (item.data.ListGetAtCol) {
        data.showData.ListGetAtCol = item.data.ListGetAtCol;
        data.showData.ListGetAtColDesc = '提取列中的值';
        data.showData.ListGetAtCol.forEach(function (chItem) {
          var defVar = vardefineInfos.find(function (x) {
            if (x.no === chItem.no) {
              return x;
            };
          });
          if (defVar) {
            chItem.area = defVar.area;
            chItem.flag = defVar.flag;
            chItem.desc = defVar.desc;
            chItem.unit = defVar.unit;
            chItem.values = defVar.values;
            chItem.defaultValue = defVar.defaultValue;
            chItem.dataType = defVar.dataType;
            chItem.level = defVar.level;
          }
          //listItemText
          chItem.listItemText = chItem.no + ', ' + chItem.desc;
          //leftIcon
          chItem.leftIconTitle = '变量信息';
          chItem.leftIcon = 'fa fa-vimeo font-blue-sharp';
          chItem.leftIconTip = '名称: ' + chItem.no
            + '<br>描述: ' + chItem.desc + '<br>单位: ' + chItem.unit
            + '<br>取值: ' + chItem.values + '<br>默认值: ' + chItem.defaultValue + '<br>标识: ' + chItem.flag;
          //rightText
          chItem.rightTextTitle = '< ' + chItem.fromCol;
        })        
      }
      
    }else if (item.type === 'LogicalBlockSelectPartTable') {
      iconTip = '表序号:'+item.orderId+'<br>表备注:'+item.name;
      //title
      data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockSelectPartTable" \
      data-original-title="选配表格" data-content=\''+iconTip+'\' \
      data-container="body" data-placement="left" ><i class="fa fa-table"></i></a> '
      +item.orderId+'.'+item.name;
      //remark
    //  data.showData.remark = item.comment;
      //条件表格信息
      // data.showData.conditionLeftIconTitle = '条件表格';
      var tempstr = '';
      item.data.conditionVars.forEach(function (pItem) {
        var defVar = vardefineInfos.find(function (x) {
          if (x.no === pItem.no) {
            return x;
          };
        });
        var conditionVarTip = '';
        if (defVar) {
          conditionVarTip = '名称: ' + defVar.no + '<br>描述: ' + defVar.desc + '<br>单位: ' + defVar.unit +
            '<br>取值: ' + defVar.values + '<br>默认值: ' + defVar.defaultValue + '<br>标识: ' + defVar.flag;
        }
        tempstr = tempstr + '<a href="#modalEditFormula" role="button" data-toggle="modal" class="hoverPopoverKeep" \
        data-original-title="变量信息" \
        data-content="' + conditionVarTip + '" \
        data-container="body"  data-placement="left" >' + pItem.no + '</a>, ';
      });
      //条件表格
      var conditionRightIconTip = '表格类型: '+item.data.condiTableType;
      var conditionRightIcon = '<a href="#modalEditSelectTable" role="button" data-toggle="modal" class="pull-right hoverPopoverKeep" \
      data-original-title="条件表格" data-content=\'' + conditionRightIconTip + '\' \
      data-container="body"  data-placement="left" ><i class="fa fa-table font-green"></i></a>';
      data.showData.condition = conditionRightIcon + tempstr;
      data.showData.condiTable = getCondiTableXY(item.data.condiTable);
      //drawnolist
      leftIconTipOpen =' <a class="pull-right" data-toggle="modal" href="#"><i class="fa fa-folder-open font-yellow-crusta"></i></a>';
      data.choices.forEach(function (chItem) {
        //leftIcon
        leftIconTitle = '件号信息';
        leftIcon = 'fa fa-bell font-green-sharp';
        leftIconTip = leftIconTipOpen+'子序号: ' + chItem.orderId
          + '<br>子件号: ' + chItem.no+ '<br>描述: ' + chItem.desc+'<br>图号: ' + chItem.drwNo+'<br>类型: ' + chItem.drwType;
        leftIconText ='<a class="hoverPopoverKeep panel-node-LogicalBlockSelectPartTable-leftIcon" \
          data-original-title=\''+leftIconTitle+'\' data-content=\''+leftIconTip+'\' data-container="body" data-placement="left">'+             
          '<i class=\''+leftIcon+'\'></i></a>';
        //listItemText
        chItem.listItemText = leftIconText+chItem.orderId+'.'+chItem.no + ', ' + chItem.desc+ ', ' + chItem.drwNo;
        //APVP,用件号替换图号做为连接线的ID
        if (chItem.drwType==='APVP') {
          chItem.drwNo=chItem.no
        }
          
      });
    }else if (item.type === 'LogicalBlockApvp') {
      var iconTip = '子件序号: ' + item.orderId + '<br>子件件号: ' + item.no + '<br>子件描述: ' + item.desc + '<br>图号类型: ' + item.drwType;
      //title
      if (item.data.isPrivate) {
        data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockApvp" \
        data-original-title="私有产品库选件" data-content="'+iconTip+'" \
        data-container="body" data-placement="left" ><i class="fa fa-ge"></i></a> '
        +item.orderId+'.'+item.name;
      } else {
        data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockApvp" \
        data-original-title="公共产品库选件" data-content="'+iconTip+'" \
        data-container="body" data-placement="left" ><i class="fa fa-leaf"></i></a> '
        +item.orderId+'.'+item.name;
      }
      //remark
      data.showData.remark = item.no + ', ' + item.desc;
      //props
      var tempstr='';
      data.showData.propTitle='BOM属性列表';
      data.showData.props=item.data.props;
      data.showData.props.forEach(function (pItem) {
        var prop = props.find(function (x) {
          if (x.propId === pItem.propId) {
            return x;
          };
        });
        //leftIcon
        leftIconTitle=prop.desc,
        leftIcon = 'fa fa-puzzle-piece font-green'
        if (pItem.propId.charAt(0)==='2') {
          leftIcon = 'fa fa-delicious font-green'
        }
        leftIconTip='属性编号: ' + pItem.propId + '<br>属性名称: ' + prop.desc + '<br>属性值: ' + pItem.value;
        //rightIcon
        rightIconTitle='',rightIconTip='',rightIcon='',colorIcon='font-red'
        if (pItem.value) {
          colorIcon='font-blue'
        }

        if (pItem.readonly) { //只读属性
          rightIconTitle = '只读属性';
          rightIconTip = '='+ pItem.value;
          rightIcon = 'fa fa-ban font-grey-silver';
        }else if (pItem.getVar) { //变量赋值
          rightIconTitle = '变量赋值';
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalSelectList"><i class="fa fa-pencil-square font-blue"></i></a>='+
          pItem.getVar.no;
          rightIcon = 'fa fa-vimeo '+colorIcon;
        }else if (pItem.condiTable) { //condition table
          rightIconTitle = '条件表格赋值';
          rightIconTip ='条件表格<a class="pull-right" data-toggle="modal" href="#modalEditPropTable"><i class="fa fa-pencil-square font-blue"></i></a>'+
          getCondiTableXY(pItem.condiTable);
          rightIcon = 'fa fa-table '+colorIcon;
        }else {
          rightIcon = 'fa fa-text-width '+colorIcon;
          rightIconTitle = '固定值赋值';
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalSelectList"><i class="fa fa-pencil-square font-blue"></i></a> = '+
          pItem.value;
        }
        leftIconText='<a href="#" role="button" data-toggle="modal" class="hoverPopoverKeep" \
                  data-original-title="'+leftIconTitle+'" data-content="'+leftIconTip+'" \
                  data-container="body" data-placement="left"><i class="'+leftIcon+'"></i></a>';             
        rightIconText='<a href="#" role="button" data-toggle="modal" class="hoverPopoverKeep pull-right" \
                  data-original-title="'+rightIconTitle+'" data-content=\''+rightIconTip+'\' \
                  data-container="body" data-placement="left"><i class="'+rightIcon+'"></i></a>';             
        pItem.listItemText = leftIconText+ prop.desc+ ' = '+ pItem.value + rightIconText;
      });
      //传入参数
      data.showData.inputparaLeftIconTitle = '传入参数';
      tempstr = ''
      item.data.inputpara.forEach(function (pItem) {
        tempstr = tempstr + pItem.no+'> '+pItem.toNo + ', ';
      });
      data.showData.inputpara = tempstr.substring(0, parseInt(item.width / 10));
      data.showData.inputparaLeftIconTip = tempstr;
      
      //返回变量
      data.showData.returnpara = item.data.returnpara;
      data.showData.returnparaDesc = '返回变量';
      data.showData.returnpara.forEach(function (chItem) {
        var defVar = vardefineInfos.find(function (x) {
          if (x.no === chItem.no) {
            return x;
          };
        });
        if (defVar) {
          chItem.area = defVar.area;
          chItem.flag = defVar.flag;
          chItem.desc = defVar.desc;
          chItem.unit = defVar.unit;
          chItem.values = defVar.values;
          chItem.defaultValue = defVar.defaultValue;
          chItem.dataType = defVar.dataType;
          chItem.level = defVar.level;
        }
        //listItemText
        chItem.listItemText = chItem.no + ', ' + chItem.desc;
        //leftIcon
        chItem.leftIconTitle = '变量信息';
        chItem.leftIcon = 'fa fa-vimeo font-blue-sharp';
        chItem.leftIconTip = '名称: ' + chItem.no
          + '<br>描述: ' + chItem.desc + '<br>单位: ' + chItem.unit
          + '<br>取值: ' + chItem.values + '<br>默认值: ' + chItem.defaultValue + '<br>标识: ' + chItem.flag;
        //rightIcon
        chItem.rightIconTitle = '返回变量';
        if (chItem.fromNo===chItem.no) {
          chItem.rightIcon = 'fa fa-arrow-circle-o-left font-blue';
        } else {
          chItem.rightIcon = 'fa fa-arrow-circle-o-left font-dark';
        }
        chItem.rightIconTip = '< ' + chItem.fromNo;
      })
    }else if (item.type === 'LogicalBlockDesignDrwNo') {
      iconTip = '<a class="pull-right" href="WebEpdFileGcsReport.html"  target="_blank"><i class="fa fa-folder-open font-yellow-crusta"></i></a> '+
      '子件序号: ' + item.orderId + '<br>子件件号: ' + item.no + '<br>子件描述: ' + item.desc + '<br>子件图号: ' + item.name+ '<br>图号类型: ' + item.drwType;
      //title
      data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockDesignDrwNo" \
      data-original-title="子件信息" data-content=\''+iconTip+'\' \
      data-container="body" data-placement="left" ><i class="fa fa-star"></i></a> '
      +item.orderId +'.'+item.name;
      //remark
      data.showData.remark = item.no + ', ' + item.desc;
      //props
      data.showData.propTitle='BOM属性列表';
      var tempstr='';
      data.showData.props=item.data.props;
      data.showData.props.forEach(function (pItem) {
        var prop = props.find(function (x) {
          if (x.propId === pItem.propId) {
            return x;
          };
        });
        //leftIcon
        leftIconTitle='BOM属性',
        leftIcon = 'fa fa-puzzle-piece font-green'
        if (pItem.propId.charAt(0)==='2') {
          leftIcon = 'fa fa-delicious font-green'
        }
        leftIconTip='属性编号: ' + pItem.propId + '<br>属性名称: ' + prop.desc + '<br>属性值: ' + pItem.value;
        //rightIcon
        rightIconTitle='',rightIconTip='',rightIcon='',colorIcon='font-red'
        if (pItem.value) {
          colorIcon='font-blue'
        }

        if (pItem.readonly) { //只读属性
          rightIconTitle = '只读属性';
          rightIconTip = '='+ pItem.value;
          rightIcon = 'fa fa-ban font-grey-silver';
        }else if (pItem.getVar) { //变量赋值
          rightIconTitle = '变量赋值';
          var defVar = vardefineInfos.find(function (x) {
            if (x.no === pItem.getVar.no) {
              return x;
            };
          });
          if (defVar) {
            conditionVarTip = '名称: ' + defVar.no + '<br>描述: ' + defVar.desc + '<br>单位: ' + defVar.unit +
              '<br>取值: ' + defVar.values + '<br>默认值: ' + defVar.defaultValue + '<br>标识: ' + defVar.flag;
            rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalSelectList"><i class="fa fa-pencil-square font-blue"></i></a>'+
              conditionVarTip;
          }
          rightIcon = 'fa fa-vimeo '+colorIcon;
        }else if (pItem.condiTable) { //condition table
          rightIconTitle = '条件表格赋值';
          rightIconTip ='条件表格<a class="pull-right" data-toggle="modal" href="#modalEditPropTable"><i class="fa fa-pencil-square font-blue"></i></a>'+
          getCondiTableXY(pItem.condiTable);
          rightIcon = 'fa fa-table '+colorIcon;
        }else if (pItem.paraTo) { //parato
          rightIconTitle = '变量向下传递';
          tempstrParato = ''
          pItem.paraTo.forEach(function (pItemParato) {
            tempstrParato = tempstrParato + pItemParato.no+'> '+pItemParato.toNo + ', ';
          });
          rightIconTip ='传递表<a class="pull-right" data-toggle="modal" href="#modalParaToTable"><i class="fa fa-pencil-square font-blue"></i></a><br>'+
          tempstrParato;
          rightIcon = 'fa fa-arrow-circle-right '+colorIcon;
        }else {
          rightIcon = 'fa fa-text-width '+colorIcon;
          rightIconTitle = '固定值赋值';
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalSelectList"><i class="fa fa-pencil-square font-blue"></i></a> = '+
          pItem.value;
        }
        leftIconText='<a href="#" role="button" data-toggle="modal" class="hoverPopoverKeep" \
                  data-original-title="'+leftIconTitle+'" data-content="'+leftIconTip+'" \
                  data-container="body" data-placement="left"><i class="'+leftIcon+'"></i></a>';             
        rightIconText='<a href="#" role="button" data-toggle="modal" class="hoverPopoverKeep pull-right" \
                  data-original-title="'+rightIconTitle+'" data-content=\''+rightIconTip+'\' \
                  data-container="body" data-placement="left"><i class="'+rightIcon+'"></i></a>';             
        pItem.listItemText = leftIconText+ prop.desc+ ':'+ pItem.value + rightIconText;
      });
    }else if (item.type === 'LogicalBlockCurPartProp') {
      var iconTip = '件号: ' + item.name + '<br>图号: ' + item.no + '<br>图号描述: ' + item.desc + '<br>详细说明: ' + item.comment+ '<br>图号类型: ' + item.drwType;
      //title
      data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockCurPartProp" \
      data-original-title="件号属性" data-content="'+iconTip+'" \
      data-container="body" data-placement="left" ><i class="fa fa-bell"></i></a> 件号属性';
      //remark
      data.showData.remark = item.desc;
      //props
      data.showData.propTitle='件属性列表';
      var tempstr='';
      data.showData.props=item.data.props;
      data.showData.props.forEach(function (pItem) {
        var prop = props.find(function (x) {
          if (x.propId === pItem.propId) {
            return x;
          };
        });
        //leftIcon
        leftIconTitle='件号属性',
        leftIconTip='属性编号: ' + pItem.propId + '<br>属性名称: ' + prop.desc + '<br>属性值: ' + pItem.value;
        //rightIcon
        rightIconTitle='',rightIconTip='',rightIcon='',colorIcon='font-red',rightIconModal=''
        if (pItem.value) {
          colorIcon='font-blue'
        }

        if (pItem.readonly) { //只读属性
          rightIconTitle = '只读属性';
          rightIconTip = '='+ pItem.value;
          rightIcon = 'fa fa-ban font-grey-silver';
        }else if (pItem.getVar) { //变量赋值
          rightIconTitle = '变量赋值';
          rightIconModal = ''
          var defVar = vardefineInfos.find(function (x) {
            if (x.no === pItem.getVar.no) {
              return x;
            };
          });
          if (defVar) {
            conditionVarTip = '名称: ' + defVar.no + '<br>描述: ' + defVar.desc + '<br>单位: ' + defVar.unit +
              '<br>取值: ' + defVar.values + '<br>默认值: ' + defVar.defaultValue + '<br>标识: ' + defVar.flag;
            rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalSelectList"><i class="fa fa-pencil-square font-blue"></i></a>'+
              conditionVarTip;
          }
          rightIcon = 'fa fa-vimeo '+colorIcon;
        }else if (pItem.condiTable) { //condition table
          rightIconTitle = '条件表格赋值';
          rightIconTip ='条件表格<a class="pull-right" data-toggle="modal" href="#modalSelectTable"><i class="fa fa-pencil-square font-blue"></i></a>'+
          getCondiTableXY(pItem.condiTable);
          rightIcon = 'fa fa-table '+colorIcon;
        }else if (pItem.getDlg) { //对话框赋值
          rightIconTitle = '对话框选择';
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalTempSample"><i class="fa fa-pencil-square font-blue"></i></a>='+
          pItem.value;
          rightIcon = 'fa fa-credit-card '+colorIcon;
        }else if (pItem.gePLib) { //关联产品库
          rightIconTitle = '关联公共产品库';
          rightIconModal = 'modalProductLibInfo'
          if(pItem.gePLib.isPrivate){rightIconTitle = '关联私有产品库';}
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalTempSample"><i class="fa fa-pencil-square font-blue"></i></a>=<br>文件夹编号:'+
          pItem.gePLib.no+'<br>梯种:'+pItem.gePLib.type+'<br>描述:'+pItem.gePLib.desc+'<br>英文描述:'+pItem.gePLib.endesc;
          rightIcon = 'fa fa-leaf '+colorIcon;
          if(pItem.gePLib.isPrivate){rightIcon = 'fa fa-ge '+colorIcon}
        }else {
          rightIcon = 'fa fa-text-width '+colorIcon;
          rightIconTitle = '固定值赋值';
          rightIconTip = '<a class="pull-right" data-toggle="modal" href="#modalSelectList"><i class="fa fa-pencil-square font-blue"></i></a> = '+
          pItem.value;
        }
        leftIconText='<a href="#" role="button" data-toggle="modal" class="hoverPopoverKeep" \
                  data-original-title="'+leftIconTitle+'" data-content="'+leftIconTip+'" \
                  data-container="body" data-placement="left"><i class="fa fa-delicious font-green"></i></a>';             
        rightIconText='<a href="#'+rightIconModal+'" role="button" data-toggle="modal" class="hoverPopoverKeep pull-right" \
                  data-original-title="'+rightIconTitle+'" data-content=\''+rightIconTip+'\' \
                  data-container="body" data-placement="left"><i class="'+rightIcon+'"></i></a>';             
        pItem.listItemText = leftIconText+ prop.desc+ ' : '+ pItem.value + rightIconText;
      });
    }else if (item.type === 'LogicalBlockGcs') {
      var iconTip = '图号: ' + item.no + '<br>描述: ' + item.desc + '<br>详细说明: ' + item.comment;
      //title
      data.showData.title = '<a class="hoverPopoverKeep titleicon-LogicalBlockGcs" \
      data-original-title="全局逻辑文件" data-content="'+iconTip+'" \
      data-container="body" data-placement="left" ><i class="fa fa-file-code-o font-white"></i></a> '
      +item.name;

      data.showData.remark = item.desc;
      var tempstr='';
      //入口参数
      data.showData.inputparaLeftIconTitle = '入口参数';
      data.showData.inputpara=''
      item.data.paras.forEach(function (pItem) {
        tempstr=tempstr+pItem.no+', ';
      });
      data.showData.inputpara = tempstr.substring(0,parseInt(item.width/10));
      data.showData.inputparaLeftIconTip = tempstr;
      //返回变量
      data.showData.returnparaLeftIconTitle = '返回变量';
      tempstr='';
      item.data.vars.forEach(function (pItem) {
        tempstr=tempstr+pItem.no+', ';
      });
      data.showData.returnpara = tempstr.substring(0,parseInt(item.width/10));
      data.showData.returnparaLeftIconTip = tempstr;
    }
    return data;

  };

  var DataDraw = {
    dblclickLine: function (conn) {
      var canDelete  = conn.endpoints[0].isSource&&conn.endpoints[1].isTarget;
      
      if (canDelete&&confirm('确定删除所点击的链接吗？')==true) {
        instJsPlumb.deleteConnection(conn)
      }
    },
    drawNode: function (nodes,vardefineInfos,props) {
      // 将Exit节点排到最后
      nodes.sort(function (a, b) {
        if (a.type === 'Exit') return 1
        if (b.type === 'Exit') return -1
        return 0
      })

      this.computeXY(nodes)

      var $container = $(configOpt.workflowArea)
      var me = this

      nodes.forEach(function (item) {
        var data = getNodeData(item, vardefineInfos,props);
       
        var templateHtmlText = me.getTemplate(item)
        //预编译模板
        var templateHandlebars = Handlebars.compile(templateHtmlText);
        var htmlStr = templateHandlebars(data);
        // console.log(htmlStr)
        $container.append(htmlStr)

        if (me['addEndpointOf' + item.type]) {
          me['addEndpointOf' + item.type](item)
        }
      })
      //设置提示框
      this.sethoverPopoverKeep();
      //bind事件
      this.bindNodeEvent();
     
    },
    bindNodeEvent:function () {
      //LogicalBlockGcs
      $('#' + configOpt.mainAreaId + ' .titleicon-LogicalBlockGcs').click(function () {
        window.open("WebEpdFileGcsReport.html"); 
      });
      $('#'+configOpt.mainAreaId+' .panel-node-LogicalBlockGcs-para').click(function () {
        $('#modalValGet-img').attr('src', "graph-para.jpg");
        $('#modalValGet').modal('show');
      });
      //LogicalBlockVar
      $('#' + configOpt.mainAreaId + ' .titleicon-LogicalBlockVar').click(function () {
        $('#modalEditFormula').modal('show');
      });
      $('#' + configOpt.mainAreaId + ' .panel-node-LogicalBlockVar-rightIcon').click(function () {
        $('#modalEditFormula').modal('show');
      });
      $('#' + configOpt.mainAreaId + ' .panel-node-LogicalBlockVar-leftIcon').click(function () {
        $('#modalValGet-img').attr('src', "graph-para.jpg");
        $('#modalValGet').modal('show');
      });
      //LogicalBlockDowhile
      $('#' + configOpt.mainAreaId + ' .titleicon-LogicalBlockDowhile').click(function () {
        $('#modalEditDowhile').modal('show');
      });
      //LogicalBlockApvp
      $('#' + configOpt.mainAreaId + ' .titleicon-LogicalBlockApvp').click(function () {
        $('#modalEditChild').modal('show');
      });
      //LogicalBlockDesignDrwNo
      $('#' + configOpt.mainAreaId + ' .titleicon-LogicalBlockDesignDrwNo').click(function () {
        $('#modalEditChild').modal('show');
      });
      //LogicalBlockCurPartProp
      $('#' + configOpt.mainAreaId + ' .titleicon-LogicalBlockCurPartProp').click(function () {
        $('#modalEditProp').modal('show');
      });
      //LogicalBlockSelectPartTable
      $('#' + configOpt.mainAreaId + ' .titleicon-LogicalBlockSelectPartTable').click(function () {
        $('#modalEditChild').modal('show');
      });

    },
    sethoverPopoverKeep:function () {
      $('#'+configOpt.mainAreaId+" .hoverPopoverKeep").popover({ trigger: "manual", html: true, animation: false })
      .on("mouseenter", function () {
        var _this = this;   // 这里的this触发的dom,需要存起来 否则在下面 .popover的逻辑中this会变为弹出的dom
        $(this).popover("show");
        $(".popover").on("mouseleave", function () {
          $(_this).popover('hide');
        });
      }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
          if (!$(".popover:hover").length) {
            $(_this).popover("hide");
          }
        }, 300);
      });
    },
    connectEndpoint: function (from, to) {
        instJsPlumb.connect({ uuids: [from, to] })        
    },
    drawConnect: function (nodes,types) {
      var me = this
      nodes.forEach(function (item) {
        if (me['connectEndpointOf' + item.type]) {
          me['connectEndpointOf' + item.type](item,types)
        }
      })
    },
    getTemplate: function (node) {
      return $('#tpl-' + node.type).html() || $('#tpl-demo').html()
    },
    computeXY: function (nodes) {
      var matrix = DataProcess.inputData(nodes)

      var base = {
        topBase: 50,
        topStep: 150,
        leftBase: 150,
        leftStep: 200
      }

      for (var i = 0; i < matrix.length; i++) {
        for (var j = 0; j < matrix[i].length; j++) {
          var key = matrix[i][j]

          var dest = nodes.find(function (item) {
            return item.id === key
          })
          if (dest) {
            dest.top = dest.top || base.topBase + i * base.topStep
            dest.left = dest.left || base.leftBase + j * base.leftStep
          }
          
        }
      }
    },
    addEndpointOfRoot: function (node) {
      initBeginNode(node.id)
    },
    connectEndpointOfRoot: function (node,types) {
      if (types&&types.flowchart){
        this.connectEndpoint(node.id + '-out', node.data.nextNode + '-in')
      }
    },
    addEndpointOfExit: function (node) {
      addDraggable(node.id)
      initEndNode(node.id)
    },
    
    //LogicalBlockIntputPara
    addEndpointOfLogicalBlockIntputPara: function (node) {
      // addDraggable(node.id)
      setEnterPoint(node.id)

      var ids = []

      node.choices.forEach(function (item) {
        ids.push('-key-' + item.no + '-R')
      })

      ids.forEach(function (key) {
        if (node.repeatId) {
          setExitPoint(node.id + key + node.repeatId, 'Right')
        } else {
          // console.log(node.id + key)
          setExitPoint(node.id + key, 'Right')
        }
      })
    },
    connectEndpointOfLogicalBlockIntputPara: function (node) {
      // var me = this
      // node.choices.forEach(function (item) {
      //   me.connectEndpoint(node.id + '-key-' + item.key + '-out', item.nextNode + '-in')
      // })
    },
    //LogicalBlockVar
    addEndpointOfLogicalBlockVar: function (node) {
      addDraggable(node.id)
      setEnterPoint(node.id, false, connectorType.flowchart)
      setExitPoint(node.id, false, connectorType.flowchart)

      var ids = []

      node.choices.forEach(function (item) {
        if (item.repeatId) {
          ids.push('key-' + item.no+'-R'+item.repeatId)
        } else {
          ids.push('key-' + item.no+'-R')
        }
      })

      ids.forEach(function (key) {
        setEnterPoint(node.id + '-' + key, 'Left')
        setExitPoint(node.id + '-' + key, 'Right')
      })
    },
    connectEndpointOfLogicalBlockVar: function (node,types) {
      var me = this
      if (types&&types.varRefLine){
        node.choices.forEach(function (item) {
          if (!item.repeatId) {
            item.repeatId = "";
          }
          var to = node.id + '-key-' + item.no + '-R' + item.repeatId + '-in';
          //赋值变量列表
          if (item.paras) {
            item.paras.forEach(para => {
              if (!para.repeatId) {
                para.repeatId = "";
              }
              var from = para.blockId + '-key-' + para.no + '-R' + para.repeatId + '-out';
              me.connectEndpoint(from, to)
            });
          }
          //GCS
          if (item.getGcs) {
            var from = item.getGcs.blockId + '-out';
            me.connectEndpoint(from, to)
          }
        });
      }
      
      if (types&&types.flowchart){
        //flowchart
        this.connectEndpoint(node.id + '-out', node.data.nextNode + '-in')
      }
    },

    //LogicalBlockApvp
    addEndpointOfLogicalBlockApvp: function (node) {
      addDraggable(node.id)
      if (node.data.linkSelectPartTable) {
        //remark out
        setExitPoint(node.id+'-remark', 'Left',connectorType.refLine)
      } else {
        setEnterPoint(node.id, false, connectorType.flowchart)
        setExitPoint(node.id, false, connectorType.flowchart)
      }
      //prop link
      node.data.props.forEach(function (item) {
        setEnterPoint(node.id + '-prop-' + item.propId, 'Left')
      })

      //inputpara in
      setEnterPoint(node.id+'-inputpara', 'Left')
      //returnpara out
      var ids = []
      node.data.returnpara.forEach(function (item) {
        ids.push('key-' + item.no+'-R')
      })
      ids.forEach(function (key) {
        setExitPoint(node.id + '-' + key, 'Left')
      })
    },
    connectEndpointOfLogicalBlockApvp: function (node,types) {
      var me = this
      if (types&&types.varRefLine){
        //prop
        node.data.props.forEach(function (propItem) {
          var to = node.id + '-prop-' + propItem.propId + '-in';
          if (propItem.getVar) {
            if (!propItem.getVar.repeatId) {
              propItem.getVar.repeatId = "";
            }
            from = propItem.getVar.blockId + '-key-' + propItem.getVar.no + '-R' + propItem.getVar.repeatId + '-out';
        //  console.log(from)
            me.connectEndpoint(from, to)
          } else if (propItem.conditionVars) {
            propItem.conditionVars.forEach(function (vari) {
              if (!vari.repeatId) {
                vari.repeatId = "";
              }
              var from = vari.blockId + '-key-' + vari.no + '-R' + vari.repeatId + '-out';
          //  console.log(from)
            me.connectEndpoint(from, to)
            });
          } else if (propItem.paraTo) {
            propItem.paraTo.forEach(function (vari) {
              if (!vari.repeatId) {
                vari.repeatId = "";
              }
              var from = vari.blockId + '-key-' + vari.no + '-R' + vari.repeatId + '-out';
            me.connectEndpoint(from, to)
            });
          }
        });
        //inputpara
        var to = node.id + '-inputpara-in';
        node.data.inputpara.forEach(function (vitem) {
          if (!vitem.repeatId) {
            vitem.repeatId="";
          }
          var from = vitem.blockId+'-key-' + vitem.no +'-R'+ vitem.repeatId + '-out';
          me.connectEndpoint(from, to)
        });
      }
      if (types&&types.flowchart){
        //nextNode
        this.connectEndpoint(node.id + '-out', node.data.nextNode + '-in')
      }
    },

    //LogicalBlockDesignDrwNo
    addEndpointOfLogicalBlockDesignDrwNo: function (node) {
      addDraggable(node.id)
      if (node.data.linkSelectPartTable) {
        //remark out
        setExitPoint(node.id+'-remark', 'Left',connectorType.refLine)
      } else {
        setEnterPoint(node.id, false, connectorType.flowchart)
        setExitPoint(node.id, false, connectorType.flowchart)
      }

      //prop link
      node.data.props.forEach(function (item) {
        setEnterPoint(node.id + '-prop-' + item.propId, 'Left')
      })

    },
    connectEndpointOfLogicalBlockDesignDrwNo: function (node, types) {
      var me = this
      if (types && types.varRefLine) {
        //prop
        node.data.props.forEach(function (propItem) {
          to = node.id + '-prop-' + propItem.propId + '-in';
          if (propItem.getVar) {
            if (!propItem.getVar.repeatId) {
              propItem.getVar.repeatId = "";
            }
            from = propItem.getVar.blockId + '-key-' + propItem.getVar.no + '-R' + propItem.getVar.repeatId + '-out';
            me.connectEndpoint(from, to)
          } else if (propItem.conditionVars) {
            propItem.conditionVars.forEach(function (vari) {
              if (!vari.repeatId) {
                vari.repeatId = "";
              }
              var from = vari.blockId + '-key-' + vari.no + '-R' + vari.repeatId + '-out';
            me.connectEndpoint(from, to)
            });
          } else if (propItem.paraTo) {
            propItem.paraTo.forEach(function (vari) {
              if (!vari.repeatId) {
                vari.repeatId = "";
              }
              var from = vari.blockId + '-key-' + vari.no + '-R' + vari.repeatId + '-out';
            me.connectEndpoint(from, to)
            });
          }
        });
      }
      if (types && types.flowchart) {
        //nextNode
        me.connectEndpoint(node.id + '-out', node.data.nextNode + '-in')
      }
    },
    //LogicalBlockCurPartProp
    addEndpointOfLogicalBlockCurPartProp: function (node) {
      addDraggable(node.id)

        // setEnterPoint(node.id, false, connectorType.flowchart)
        // setExitPoint(node.id, false, connectorType.flowchart)

      //prop link
      node.data.props.forEach(function (item) {
        setEnterPoint(node.id + '-prop-' + item.propId, 'Left')
      })

    },
    connectEndpointOfLogicalBlockCurPartProp: function (node, types) {
      var me = this
      if (types && types.varRefLine) {
        //prop
        node.data.props.forEach(function (propItem) {
          to = node.id + '-prop-' + propItem.propId + '-in';
          if (propItem.getVar) {
            if (!propItem.getVar.repeatId) {
              propItem.getVar.repeatId = "";
            }
            from = propItem.getVar.blockId + '-key-' + propItem.getVar.no + '-R' + propItem.getVar.repeatId + '-out';
            me.connectEndpoint(from, to)
          } else if (propItem.conditionVars) {
            propItem.conditionVars.forEach(function (vari) {
              if (!vari.repeatId) {
                vari.repeatId = "";
              }
              var from = vari.blockId + '-key-' + vari.no + '-R' + vari.repeatId + '-out';
            me.connectEndpoint(from, to)
            });
          } else if (propItem.paraTo) {
            propItem.paraTo.forEach(function (vari) {
              if (!vari.repeatId) {
                vari.repeatId = "";
              }
              var from = vari.blockId + '-key-' + vari.no + '-R' + vari.repeatId + '-out';
            me.connectEndpoint(from, to)
            });
          }
        });
      }
      // if (types && types.flowchart) {
      //   //nextNode
      //   me.connectEndpoint(node.id + '-out', node.data.nextNode + '-in')
      // }
    },

    //LogicalBlockDowhile
    addEndpointOfLogicalBlockDowhile: function (node) {
      addDraggable(node.id)
      setEnterPoint(node.id, false, connectorType.flowchart)
      //condition in
      setEnterPoint(node.id+'-condition', 'Left')
      //loop in
      setEnterPoint(node.id + "-Loop", 'BottomRight', connectorType.flowchart)
      setExitPoint(node.id, false, connectorType.flowchart)
      //dowhile out
      setExitPoint(node.id+'-Dowhile', 'Right', connectorType.flowchart)

    },
    connectEndpointOfLogicalBlockDowhile: function (node,types) {
      var me = this

      var to = node.id + '-condition-in';
      if (types&&types.varRefLine){
        node.data.conditionVars.forEach(function (vitem) {
          if (!vitem.repeatId) {
            vitem.repeatId="";
          }
          var from = vitem.blockId+'-key-' + vitem.no +'-R'+ vitem.repeatId + '-out';
          me.connectEndpoint(from, to)

        });
      }
      if (types&&types.flowchart){
        //连接下一节点
        this.connectEndpoint(node.id + '-out', node.data.nextNode + '-in')
        //连接dowhile的下一节点
        this.connectEndpoint(node.id + '-Dowhile-out', node.data.nextNodeDowhile + '-in')
      }
    },
    //LogicalBlockSelectPartTable
    addEndpointOfLogicalBlockSelectPartTable: function (node) {
      addDraggable(node.id)
      setEnterPoint(node.id, false, connectorType.flowchart)
      //condition in
      setEnterPoint(node.id+'-condition', 'Left')
      setExitPoint(node.id, false, connectorType.flowchart)

      //drawnolist
      var ids = []
      node.choices.forEach(function (item) {
          ids.push('drawno-' + item.drwNo+"-"+item.orderId)
      })
      ids.forEach(function (key) {
        setEnterPoint(node.id + '-' + key, 'Right',connectorType.refLine)
      })

    },
    connectEndpointOfLogicalBlockSelectPartTable: function (node,types) {
      var me = this
      if (types&&types.varRefLine){
          //选配表格
        var to = node.id + '-condition-in';
        node.data.conditionVars.forEach(function (vitem) {
          if (!vitem.repeatId) {
            vitem.repeatId="";
          }
          var from = vitem.blockId+'-key-' + vitem.no +'-R'+ vitem.repeatId + '-out';
          me.connectEndpoint(from, to)
        });
      }
      //图号列表
      node.choices.forEach(function (item) {
        var drawnoId = node.id + '-drawno-' + item.drwNo+"-"+item.orderId;
        var partBlockId = item.blockId;
        me.connectEndpoint(partBlockId + '-remark-out', drawnoId + '-in')
      });
      if (types&&types.flowchart){
        //连接下一节点
      this.connectEndpoint(node.id + '-out', node.data.nextNode + '-in')
      }
    },


    //LogicalBlockGcs
    addEndpointOfLogicalBlockGcs: function (node) {
      addDraggable(node.id)

      setExitPoint(node.id, 'Right')

    },
    connectEndpointOfLogicalBlockGcs: function (node,types) {
      // this.connectEndpoint(node.id + '-onLogicalBlock-out', node.data.onWorkNode + '-in')
      // this.connectEndpoint(node.id + '-offLogicalBlock-out', node.data.offWorkNode + '-in')
    },

    //LogicalBlock
    addEndpointOfLogicalBlock: function (node) {
      addDraggable(node.id)
      setEnterPoint(node.id,false,connectorType.flowchart)

      var ids = ['onLogicalBlock', 'offLogicalBlock']

      ids.forEach(function (key) {
        setExitPoint(node.id + '-' + key, 'Right')
      })
    },
    connectEndpointOfLogicalBlock: function (node,types) {
      this.connectEndpoint(node.id + '-onLogicalBlock-out', node.data.onWorkNode + '-in')
      this.connectEndpoint(node.id + '-offLogicalBlock-out', node.data.offWorkNode + '-in')
    },

  };
  // 主要入口
  function mainInit (config) {
    //合并选项
    configOpt = $.extend(configOpt, config);
    // 设置主区域中的子区域的最大高度
    $('.mainAreaJsPlumb .areaJsPlumb').height(configOpt.dataWorkflow.height||800);
    instJsPlumb.setContainer(configOpt.mainAreaId)

    $('.btn-controler').draggable({
      helper: 'clone',
      scope: 'ss'
    })

    $(configOpt.workflowArea).droppable({
      scope: 'ss',
      drop: function (event, ui) {
        dropNode(ui.draggable[0].dataset.template, ui.position)
      }
    })

    $(configOpt.mainArea).on('click', function (event) {
      // event.stopPropagation()
      // event.preventDefault()
      eventHandler(event.target)
    })

    // 双击删除连接线
    instJsPlumb.bind('dblclick', function (conn, originalEvent) {
      DataDraw.dblclickLine(conn)
    })

    // 当链接建立
    instJsPlumb.bind('beforeDrop', function (info) {
      return connectionBeforeDropCheck(info)
    })

  };
  //初始化
  var drawNodeConnections = function (types) {
    DataDraw.drawConnect(configOpt.dataWorkflow.nodeList,types)
  };
  //初始化
  var deleteNodeConnections = function (types) {
    // DataDraw.drawConnect(configOpt.dataWorkflow.nodeList,types)
  };
  //初始化
  var drawNode = function () {
    DataDraw.drawNode(configOpt.dataWorkflow.nodeList, configOpt.dataWorkflow.vardefineInfos,configOpt.dataWorkflow.props)
  };

  return {
    init: function () {
      instJsPlumb = jsPlumb.getInstance();
      instJsPlumb.importDefaults({
        ConnectionsDetachable: false
      })
    },
    //初始化,设置选项,设置节点数据
    initComplateFlow: function (config) {
      mainInit(config);
    },
    //在初始后,画节点
    drawComplateFlowNode:function(){
      drawNode();
    },
    //在初始后,画节点后,画连接线
    drawComplateFlowConnections:function(types){
      drawNodeConnections(types);
    },
    //在初始后,画节点后,画连接线后,删除线
    deleteComplateFlowConnections:function(types){
      deleteNodeConnections(types);
    },
    //初始化
    showComplateFlow:function(config){
      mainInit(config);
      drawNode();
      // drawNodeConnections({flowchart:true,varRefLine:true});
      drawNodeConnections({flowchart:true});
    },
  };
}();




